package edu.hrbu.kwaidu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.hrbu.kwaidu.exception.CustomException;
import edu.hrbu.kwaidu.mapper.SysRoleMapper;
import edu.hrbu.kwaidu.model.entity.SysRole;
import edu.hrbu.kwaidu.model.vo.SysRoleQueryVo;
import edu.hrbu.kwaidu.service.SysRoleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static edu.hrbu.kwaidu.constant.SystemConstant.*;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author xudengyu
 * @since 2023-12-29
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    /**
     * 条件分页
     *
     * @param page           页号
     * @param limit          条数
     * @param sysRoleQueryVo 查询条件
     * @return page
     */
    @Override
    public Page<SysRole> pageCondition(Integer page, Integer limit, SysRoleQueryVo sysRoleQueryVo) {
        Page<SysRole> pageParam = new Page<>(page, limit);
        LambdaQueryWrapper<SysRole> sysRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleLambdaQueryWrapper.ne(SysRole::getId, SYSTEM_ROOT_ID);
        if (!BeanUtil.isEmpty(sysRoleQueryVo)) {
            doProcessCondition(sysRoleLambdaQueryWrapper, sysRoleQueryVo);
        }
        pageParam = page(pageParam, sysRoleLambdaQueryWrapper);
        return pageParam;
    }

    /**
     * 处理条件查询
     *
     * @param sysRoleLambdaQueryWrapper wrapper
     * @param sysRoleQueryVo            vo
     */
    private void doProcessCondition(LambdaQueryWrapper<SysRole> sysRoleLambdaQueryWrapper, SysRoleQueryVo sysRoleQueryVo) {
        String roleName = sysRoleQueryVo.getRoleName();
        if (!StrUtil.isBlank(roleName)) {
            sysRoleLambdaQueryWrapper.like(SysRole::getRoleName, roleName);
        }
    }

    /**
     * 通过主键获取基本信息
     *
     * @param id 主键
     * @return sysRole
     */
    @Override
    public SysRole getInfoById(Long id) {
        SysRole sysRole = getById(id);
        return sysRole;
    }

    /**
     * 添加|修改
     *
     * @param sysRole 系统角色
     */
    @Override
    public void addOrEdit(SysRole sysRole) {
        checkRoleBaseInfo(sysRole);
        boolean f = false;
        Long roleId = sysRole.getId();
        String roleName = sysRole.getRoleName();
        String roleCode = sysRole.getRoleCode();
        String description = sysRole.getDescription();
        SysRole dbRole = getRoleByRoleName(roleName);
        checkRepeatRoleName(sysRole, dbRole);
        if (roleId == null) { // add
            f = save(sysRole);
        } else { // edit
            LambdaUpdateWrapper<SysRole> sysRoleLambdaQueryWrapper = new LambdaUpdateWrapper<>();
            sysRoleLambdaQueryWrapper.eq(SysRole::getId, roleId)
                    .set(SysRole::getRoleName, roleName)
                    .set(SysRole::getRoleCode, roleCode)
                    .set(SysRole::getDescription, description);
            f = update(sysRoleLambdaQueryWrapper);
        }
        if (!f) {
            throw new CustomException(EXCEPTION_UPDATE_FAIL);
        }
    }

    /**
     * 检查roleName是否重复
     *
     * @param originRole 待修改的role
     * @param dbRole     库中的role
     */
    private void checkRepeatRoleName(SysRole originRole, SysRole dbRole) {
        if (dbRole == null)
            return;
        if (originRole.getId() == null)
            throw new CustomException(EXCEPTION_ROLE_NAME_REPEAT);
        if (!originRole.getRoleName().equals(dbRole.getRoleName()))
            throw new CustomException(EXCEPTION_ROLE_NAME_REPEAT);
    }

    /**
     * roleName >> role
     *
     * @param roleName 角色名称
     * @return sysRole
     */
    private SysRole getRoleByRoleName(String roleName) {
        LambdaQueryWrapper<SysRole> sysRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleLambdaQueryWrapper.eq(SysRole::getRoleName, roleName);
        return getOne(sysRoleLambdaQueryWrapper);
    }

    /**
     * 检查sysRole基本信息
     *
     * @param sysRole 系统角色
     */
    private void checkRoleBaseInfo(SysRole sysRole) {
        Long roleId = sysRole.getId();
        String roleName = sysRole.getRoleName();
        String roleCode = sysRole.getRoleCode();
        String description = sysRole.getDescription();
        if (roleId != null)
            checkInvaildModify(sysRole.getId());
        if (StrUtil.hasBlank(roleName, roleCode, description))
            throw new CustomException(EXCEPTION_USER_INFO_BLANK);
    }

    /**
     * 检查是否操作管理员数据
     *
     * @param roleId 角色主键
     */
    private void checkInvaildModify(Long roleId) {
        if (SYSTEM_ROOT_ID == roleId)
            throw new CustomException(EXCEPTION_NO_AUTH);
    }

    /**
     * 删除
     *
     * @param id 角色主键
     */
    @Override
    public void del(Long id) {
        checkInvaildModify(id);
        removeById(id);
    }

    /**
     * 批量删除
     *
     * @param ids 主键列表
     */
    @Override
    @Transactional
    public void delBatch(ArrayList<Long> ids) {
        ids.forEach(this::del);
    }

    /**
     * 获取角色列表[不包括ROOT]
     *
     * @return list
     */
    @Override
    public List<SysRole> getList() {
        LambdaQueryWrapper<SysRole> sysRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleLambdaQueryWrapper.ne(SysRole::getId, SYSTEM_ROOT_ID);
        return list(sysRoleLambdaQueryWrapper);
    }
}
